package com.pig.easy.bpm.service.impl;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.pig.easy.bpm.dto.response.TreeDTO;
import com.pig.easy.bpm.entity.ConfigDO;
import com.pig.easy.bpm.utils.CommonUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * todo:
 *
 * @author : pig
 * @date : 2020/5/16 15:28
 */
@Slf4j
public class BeseServiceImpl<M extends BaseMapper<T>, T>  {

    final static Integer DEFAULT_PAGE_INDEX = 1;

    final static Integer DEFAULT_PAGE_SIZE = 10;

    final static Integer MAX_PAGE_SIZE = 100000;

    final static int INVALID_STATE = 0;

    final static int VALID_STATE = 1;


    public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

    public static List<TreeDTO> makeTree(List<TreeDTO> treeList, Long parentId) {

        List<TreeDTO> tempList = new ArrayList<>();
        for(TreeDTO treeDTO : treeList){
            if(parentId.equals(treeDTO.getParentId())) {
                tempList.add(findChildren(treeDTO, treeList, treeDTO.getTreeId()));
            }
        }
        return tempList;
    }

    public static TreeDTO findChildren(TreeDTO treeDTO, List<TreeDTO> treeList, Long parentId) {
        List<TreeDTO> children = treeList.stream().filter(x -> parentId.equals(x.getParentId())).collect(Collectors.toList());
        children.forEach(x ->
                {
                    if (treeDTO.getChildren() == null) {
                        treeDTO.setChildren(new ArrayList<>());
                    }
                    treeDTO.getChildren().add(findChildren(x,treeList, x.getTreeId()));
                }
        );

        return treeDTO;
    }

    public static Object getConfigValueByKey(ConfigDO config) {

        if (config == null) {
            return null;
        }
        Object obj = null;
        switch (config.getConfigType().toLowerCase()) {
            case "string":
                obj = config.getConfigValue();
                break;
            case "int":
            case "integer":
                obj = CommonUtils.evalInt(config.getConfigValue());
                break;
            case "long":
                obj = CommonUtils.evalLong(config.getConfigValue());
                break;
            case "boolean":
                obj = CommonUtils.evalBoolean(config.getConfigValue());
                break;
            case "double":
                obj = CommonUtils.evalDouble(config.getConfigValue());
                break;
            case "float":
                obj = CommonUtils.evalFloat(config.getConfigValue());
                break;
            case "date":
                obj = CommonUtils.evalDate(config.getConfigValue());
                break;
            default:
                obj = config.getConfigValue();
                break;
        }
        return obj;
    }
}
